//  IDVI 1.0 source copyright 1996 Garth A. Dickie
//
//  This source is free for non-commercial use.  No warranty, etc.
//  Please acknowledge reuse by including the line:
//
//  "Based in part on IDVI 1.0 source copyright 1996 Garth A. Dickie"
//
//  in your documentation and source code.  For commercial use or
//  distribution, please contact the author.  Please also send
//  questions, comments, bug reports, or fixes.
//
//  Best Regards,
//  Garth A. Dickie
//  dickie@elastic.avid.com

package ibook.v10.idvi.dvi;

import java.io.*;
import java.util.*;
import java.net.*;

import ibook.v10.idvi.*;
import ibook.v10.idvi.io.*;
import ibook.v10.idvi.display.BlockRoot;
import ibook.v10.idvi.display.PageParser;

public class DVIStreamDocument extends DVIDocument implements Runnable {
    private Vector          page = new Vector( );
    private boolean         doneLoading = false;
    private DVITokenizer    tokenizer;
    private PageParser      parser;
    private MessageContext  context;        // context which loaded us first...

    public DVIStreamDocument( InputStream inputStream, int dpi, URL fontBase, MessageContext context )
            throws IOException, DVIFormatException {
        
        this.context = context;

        DVIInputStream source = new DVIInputStream( inputStream );

        setDPI( dpi );
        setFontBase( fontBase );
        parseHeader( source );

        tokenizer = new DVITokenizer( source, this, context );
        parser = new PageParser( tokenizer, this, 0 );

        Thread loader = new Thread( this );
        loader.start( );
    }

    public synchronized BlockRoot getPage( int index ) {
        BlockRoot result;

        if( index >= 0 )
            while( index >= page.size( ) && ! doneLoading )
                try {
                    wait( );
                } catch( InterruptedException e ) {
                }

        if( index >= 0 && index < page.size( ))
            result = ( BlockRoot )( page.elementAt( index ));
        else
            result = null;
        
        return result;
    }

    public synchronized int getPageCount( ) {
        while( ! doneLoading )
            try {
                wait( );
            } catch( InterruptedException e ) {
            }
        
        return page.size( );
    }

    public synchronized int clipPageNumber( int pageNumber ) {
        if( pageNumber >= 0 )
            while( pageNumber >= page.size( ) && ! doneLoading )
                try {
                    wait( );
                } catch( InterruptedException e ) {
                }
        
        return Math.min( page.size( ) - 1, pageNumber );
    }

    private synchronized void addPage( BlockRoot newPage ) {
        page.addElement( newPage );
        notifyAll( );
    }

    private synchronized void setDoneLoading( ) {
        doneLoading = true;
        notifyAll( );
    }

    public void run( ) {
        Thread.currentThread( ).setPriority( IDVI.kPriorityLoadDocument );

        try {
            while( tokenizer.token == DVITokenizer.kTokenBeginPage ) {
                BlockRoot root = parser.startPage( );
                addPage( root );
                parser.finishPage( root );
                Thread.currentThread( ).yield( );
            }
            parser.close( );
            context.showMessage( "Done loading" );
        } catch( Exception e ) {
            context.showMessage( "Exception while loading" );
            e.printStackTrace( System.err );
        } finally {
            setDoneLoading( );
        }
    }
}
